package com.vogue.supplymall.order.domain.biz.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.vogue.sprakka.client.future.FutureWrapper;
import com.vogue.configs.springextend.remote.DelegateResource;
import com.vogue.gear.memory.provider.IMemProvider;
import com.vogue.supplymall.admin.business.common.constant.CachedPayValues;
import com.vogue.supplymall.admin.business.common.constant.CachedTsPayValues;
import com.vogue.supplymall.admin.business.common.inter.bean.InterCachePayValues;
import com.vogue.supplymall.common.constant.ConstantBean;
import com.vogue.supplymall.common.constant.ConstantBean.EnumShopPaymode;
import com.vogue.supplymall.common.constant.ErrorCode;
import com.vogue.supplymall.common.constant.OrderStatusEnum;
import com.vogue.supplymall.common.domain.dto.MultiplePayInfo;
import com.vogue.supplymall.common.domain.dto.MultiplePayOrderInfo;
import com.vogue.supplymall.common.domain.dto.OrderInfo;
import com.vogue.supplymall.common.domain.dto.PaymentInfo;
import com.vogue.supplymall.common.domain.dto.UserInfo;
import com.vogue.supplymall.common.domain.tool.MessageSourceUtils;
import com.vogue.supplymall.common.domain.tool.VestUtils;
import com.vogue.supplymall.order.domain.biz.OrderPayBiz;
import com.vogue.supplymall.order.domain.biz.OrderPayOfflineBiz;
import com.vogue.supplymall.order.domain.biz.OrderPayOnlineBiz;
import com.vogue.supplymall.order.domain.biz.OrderUpdateBiz;
import com.vogue.supplymall.order.domain.model.Order;
import com.vogue.supplymall.order.domain.model.OrderItem;
import com.vogue.supplymall.order.domain.model.OrderItemProduct;
import com.vogue.supplymall.order.domain.model.OrderPayment;
import com.vogue.supplymall.order.domain.model.OrderSeller;
import com.vogue.supplymall.order.domain.model.OrderBuyer;
import com.vogue.supplymall.order.domain.model.OrderStatus;
import com.vogue.supplymall.match.domain.model.MatchOrgan;
import com.vogue.supplymall.order.domain.service.OrderItemProductService;
import com.vogue.supplymall.order.domain.service.OrderItemService;
import com.vogue.supplymall.order.domain.service.OrderPaymentService;
import com.vogue.supplymall.order.domain.service.OrderSellerService;
import com.vogue.supplymall.order.domain.service.OrderBuyerService;
import com.vogue.supplymall.order.domain.service.OrderService;
import com.vogue.supplymall.order.domain.service.OrderStatusService;
import com.vogue.supplymall.match.domain.service.MatchOrganService;
import com.vogue.supplymall.order.exception.MergePayDisagreeException;
import com.vogue.supplymall.order.exception.OrderIsTimeOverException;
import com.vogue.supplymall.order.exception.PayFailException;
import com.vogue.supplymall.order.exception.PaymentConflictException;
import com.vogue.supplymall.order.exception.ShopRefusePaymentException;
import com.vogue.supplymall.payment.api.WuXiangPayment;
import com.vogue.supplymall.payment.dto.BaseResultParameter;
import com.vogue.supplymall.payment.dto.BaseSimpleInputParameter;
import com.vogue.supplymall.payment.dto.IResultParameter;
import com.vogue.supplymall.payment.dto.InputParameterOrder;
import com.vogue.supplymall.payment.dto.InputParameterOrderItem;
import com.vogue.supplymall.payment.dto.MultiplePayInputParameter;
import com.vogue.supplymall.payment.dto.MultiplePayOrder;
import com.vogue.supplymall.payment.dto.MultiplePayOrderItem;
import com.vogue.supplymall.payment.dto.PayQueryInputParameter;
import com.vogue.supplymall.payment.dto.PayQueryResultParameter;
import com.vogue.supplymall.payment.dto.SinglePayInputParameter;
import com.vogue.supplymall.shop.domain.model.Shop;
import com.vogue.supplymall.shop.domain.service.ShopService;

/**
 * 支付业务处理Worker
 * @author cy
 */
@Service("orderPayBiz")
public class OrderPayBizImpl implements OrderPayBiz {

    public static final Logger LOGGER_ORDERPAYBIZIMPL = LoggerFactory.getLogger(OrderPayBizImpl.class);

    @Resource
    private OrderUpdateBiz orderUpdateBiz;
    @Resource
    private OrderPayOfflineBiz orderPayOfflineBiz;
    @Resource
    private OrderPayOnlineBiz orderPayOnlineBiz;
    @Resource
    private OrderService orderService;
    @Resource
    private OrderStatusService orderStatusService;
    @Resource
    private OrderSellerService orderSellerService;
    @Resource
    private OrderItemService orderItemService;
    @Resource
    private OrderItemProductService orderItemProductService;
    @Resource
    private OrderPaymentService orderPaymentService;
    @Resource
    private ShopService shopService;
    @Resource
    private OrderBuyerService orderBuyerService;
    @Resource
    private MatchOrganService matchOrganService;
    @Autowired
    private MessageSourceUtils messageSourceUtils;
    @DelegateResource
    private WuXiangPayment wuXiangPayment;
    @Resource(name = "memProvider")
    private IMemProvider<Object> memProvider;

    /**
     * 合并支付处理（单笔的也可以调用此方法）
     * @param multiplePayInfo 合并支付数据封装DTO
     * @return 结果返回信息
     */
    @Override
    @Transactional
    public IResultParameter orderPay(MultiplePayInfo multiplePayInfo) {
        IResultParameter result = null;
        try {
            LOGGER_ORDERPAYBIZIMPL.debug("支付接口调用，封装数据：{}", multiplePayInfo.toString());
            orderPaymentValidation(multiplePayInfo);
//            payModelEffectiveValidation(multiplePayInfo);
            if (VestUtils.isPayTogether() || VestUtils.isDelayEntryMode()) {
                result = payMultiple(multiplePayInfo);
            } else {
                result = paySingle(multiplePayInfo); 
            }            
        } catch (OrderIsTimeOverException ex) {
            Order order = orderService.get(Long.parseLong(ex.getOrderFlag()));
            if (order == null) {
                order = orderService.selectOneByWhr("ordernumber='" + ex.getOrderFlag() + "'");
            }
            if (order != null) {
                OrderStatus orderStatus = orderStatusService.selectOneByWhr("orderid=" + order.getId());
                orderStatus.setIscancel(true);
                orderStatus.setModifyDate(new Date());
                orderStatusService.update(orderStatus);
                /*更新商品计划*/
                orderUpdateBiz.returnProductInventory(order.getId());
                LOGGER_ORDERPAYBIZIMPL.debug("编号【{}】的订单超时自动取消！", order.getOrdernumber());
                result = new BaseResultParameter();
                result.setReturnCode(ConstantBean.WUXIANG_FAIL_RETURNCODE);
                result.setErrorCode(String.valueOf(ErrorCode.OrderIsTimeOver.getCode()));
                result.setErrorText(order.getOrdernumber());
            } else {
                LOGGER_ORDERPAYBIZIMPL.error("没有找到必要的订单信息，关键字：{}", ex.getOrderFlag());
                result = new BaseResultParameter();
                result.setReturnCode(ConstantBean.WUXIANG_FAIL_RETURNCODE);
                result.setErrorCode("0");
                result.setErrorText(messageSourceUtils.getMessage("global.system.order", null));
            }
        } 
        return result;        
    }

    /**
     * 单笔支付处理(立即支付)--事务层
     * @param multiplePayInfo 订单信息列表
     * @return 结果返回信息
     */
    @SuppressWarnings("unchecked")
    public IResultParameter paySingle(MultiplePayInfo multiplePayInfo) {
        IResultParameter result = new BaseResultParameter();
        result.setReturnCode(ConstantBean.WUXIANG_SUCCESS_RETURNCODE);
        result.setErrorCode(ConstantBean.WUXIANG_SUCCESS_ERRORCODE.toString());
        result.setErrorText(messageSourceUtils.getMessage("order.pay.success", null));
        List<MultiplePayOrderInfo> orderList = multiplePayInfo.getOrders();
        if (orderList != null) {
           if (!VestUtils.isPayTogether() && orderList.size() > 1) {
               throw new MergePayDisagreeException();
           }
        } else {
            return result;
        }
        
        for (MultiplePayOrderInfo payorder : orderList) {
            try {
                orderUpdateBiz.deleteAllPayment(payorder.getOrderid());
            } catch (Exception ex) {
                LOGGER_ORDERPAYBIZIMPL.error("订单编号[{}]保存新支付记录前清空旧支付记录失败，原因：{}", payorder.getOrderid(), ex.getMessage());
                throw new PayFailException(ex.getMessage());
            }
            List<Integer> combinationPaymodeList = new ArrayList<>(); //已经支付过的可组合的直接支付方式的集合
            for (PaymentInfo payment : payorder.getPaymentList()) {
                if (ConstantBean.COMBINATION_PAYMENT_ALLOW.contains(payment.getPaymentMode())) {
                    OrderStatus orderStatus = null;
                    if (payment.getPaymentMode() == ConstantBean.EnumPaymentMode.UnderLine.getCode()) {
                        orderStatus = orderPayOfflineBiz.orderPayOfflineTs(payorder.getOrderid(), payment.getMoney());
                    } else {
                        IResultParameter rp = orderPayOnlineBiz.orderPayOnline(payment.getPaymentMode(),
                                getWuxiangPaytypeid(payment.getPaymentMode()),
                                payorder.getOrderid(), payment.getRedirectUrl(), payment.getMoney());
                        orderStatus = (OrderStatus) rp.getData();
                    }
                    combinationPaymodeList.add(payment.getPaymentMode());
                    if (combinationPaymodeList.size() == payorder.getPaymentList().size()) {
                        if (orderStatus == null) {
                            LOGGER_ORDERPAYBIZIMPL.error("订单id{}的订单状态信息不存在", payorder.getOrderid());
                        } else {
                            orderUpdateBiz.saveOrderStateByShopWaitingOrder(orderStatus);
                        }                         
                    }                
                } else {
                    Order order = orderService.get(payorder.getOrderid());
                    OrderSeller os = orderSellerService.selectOneByWhr("orderid=" + payorder.getOrderid());
                    OrderBuyer buyer = orderBuyerService.selectOneByWhr("orderid=" + payorder.getOrderid());
                    List<OrderItem> oiList = orderItemService.selectByWhr("orderid=" + payorder.getOrderid());
                    List<OrderItemProduct> list = orderItemProductService.selectByWhr("orderid=" + payorder.getOrderid());
                    MatchOrgan organ = matchOrganService.get(buyer.getOrganid());            
                    
                    InputParameterOrder inputOrder = new InputParameterOrder();
                    inputOrder.setBilldismoney(0.0);
                    inputOrder.setBillmoney(0.0);
                    inputOrder.setCardflag(0);
                    inputOrder.setDismoney(0.0);
                    inputOrder.setMoney(payment.getMoney().doubleValue());
                    inputOrder.setOrderid(order.getOrdernumber());
                    inputOrder.setStoreid(os.getMcid());
                    
                    List<InputParameterOrderItem> payDataItemInfoList = new ArrayList<>();
                    for (OrderItemProduct oip : list) {
                        InputParameterOrderItem payDataItemInfo = new InputParameterOrderItem();
                        payDataItemInfo.setItemid(String.valueOf(oip.getProductid()));
                        payDataItemInfo.setItemname(oip.getPname());
                        payDataItemInfo.setPrice(oip.getPrice().doubleValue());
                        for (OrderItem oi : oiList) {
                            if (oip.getOrderitemid().equals(oi.getId())) {
                                payDataItemInfo.setItemcount(oi.getItemquantity());
                            }
                        }
                        payDataItemInfoList.add(payDataItemInfo);
                    }
                    
                    inputOrder.setItems(payDataItemInfoList);
                    
                    SinglePayInputParameter singlePayInputParameter = new SinglePayInputParameter();
                    singlePayInputParameter.setPaytypeid(getWuxiangPaytypeid(multiplePayInfo.getUnificationPayment()));
                    singlePayInputParameter.setData(inputOrder);
                    singlePayInputParameter.setClientIp(getClientIp());
                    singlePayInputParameter.setMoney(inputOrder.getMoney());
                    singlePayInputParameter.setOrderid(inputOrder.getOrderid());
                    singlePayInputParameter.setPaystoreid(organ.getMcid());
                    singlePayInputParameter.setRedirectUrl(multiplePayInfo.getRedirectUrl());
                    singlePayInputParameter.setStoreid(inputOrder.getStoreid());
                    if (payment.getPaymentMode() == ConstantBean.EnumPaymentMode.WuXiang.getCode()) {
                        singlePayInputParameter.setData(null);
                    } 
                    createPayment(payorder.getOrderid(), payment.getMoney(), payment.getPaymentMode());
                    result = orderPayOnlineBiz.singlePayOnline(singlePayInputParameter);
                    if (result.getReturnCode() != 1) {
                        throw new PayFailException(result.getErrorText());
                    } else {
                        if (result.getData() != null) {
                            Map<String, Object> map  = ((Map<String, Object>) result.getData());
                            map.put("orderid", payorder.getOrderid());
                        }
                    }    
                }         
            }
        }
        return result;
    }
    
    /**
     * 合并支付处理--事务层（单笔也可以走此方法）
     * @param multiplePayInfo 订单信息列表
     * @return 结果返回信息
     */
    @SuppressWarnings("unchecked")
    public IResultParameter payMultiple(MultiplePayInfo multiplePayInfo) {
        IResultParameter result = new BaseResultParameter();
        result.setReturnCode(ConstantBean.WUXIANG_SUCCESS_RETURNCODE);
        result.setErrorCode(ConstantBean.WUXIANG_SUCCESS_ERRORCODE.toString());
        result.setErrorText(messageSourceUtils.getMessage("order.pay.success", null));
        List<MultiplePayOrderInfo> orderList = multiplePayInfo.getOrders();
        if (orderList != null) {
           if (!VestUtils.isPayTogether() && orderList.size() > 1) {
               throw new MergePayDisagreeException();
           }
        } else {
            return result;
        }
        Long orderid = 0L;
        MultiplePayInputParameter multiplePayInputParameter = new MultiplePayInputParameter();
        multiplePayInputParameter.setPaytypeid(getWuxiangPaytypeid(multiplePayInfo.getUnificationPayment()));
        List<MultiplePayOrder> orderDetailList = new ArrayList<>(); //封装支付接口需要的订单数据集合
        for (MultiplePayOrderInfo order : orderList) {
            try {
                orderUpdateBiz.deleteAllPayment(order.getOrderid());
            } catch (Exception ex) {
                LOGGER_ORDERPAYBIZIMPL.error("订单编号[{}]保存新支付记录前清空旧支付记录失败，原因：{}", order.getOrderid(), ex.getMessage());
                throw new PayFailException(ex.getMessage());
            }
            List<Integer> combinationPaymodeList = new ArrayList<>(); //已经支付过的可组合的直接支付方式的集合
            for (PaymentInfo payment : order.getPaymentList()) {
                if (ConstantBean.COMBINATION_PAYMENT_ALLOW.contains(payment.getPaymentMode())) {
                    OrderStatus orderStatus = null;
                    if (payment.getPaymentMode() == ConstantBean.EnumPaymentMode.UnderLine.getCode()) {
                        orderStatus = orderPayOfflineBiz.orderPayOfflineTs(order.getOrderid(), payment.getMoney());
                    } else {
                        IResultParameter rp = orderPayOnlineBiz.orderPayOnline(payment.getPaymentMode(),
                                getWuxiangPaytypeid(payment.getPaymentMode()),
                                order.getOrderid(), payment.getRedirectUrl(), payment.getMoney());
                        orderStatus = (OrderStatus) rp.getData();
                    }
                    combinationPaymodeList.add(payment.getPaymentMode());
                    if (combinationPaymodeList.size() == order.getPaymentList().size()) {
                        if (orderStatus == null) {
                            LOGGER_ORDERPAYBIZIMPL.error("订单id{}的订单状态信息不存在", order.getOrderid());
                        } else {
                            orderUpdateBiz.saveOrderStateByShopWaitingOrder(orderStatus);
                        }                         
                    }                
                } else {
                    if (multiplePayInfo.getUnificationPayment().equals(payment.getPaymentMode())) {
                        orderid = order.getOrderid();
                        createPayment(order.getOrderid(), payment.getMoney(), multiplePayInfo.getUnificationPayment());
                        orderDetailList.add(getPayOrder(order.getOrderid(), payment.getMoney()));
                        multiplePayInputParameter.setMoney((new BigDecimal(multiplePayInputParameter.getMoney())
                                .setScale(2, BigDecimal.ROUND_HALF_DOWN).add(payment.getMoney().setScale(2, BigDecimal.ROUND_HALF_DOWN))).doubleValue());
                    } else {
                        throw new PaymentConflictException();
                    }
                }
            }
        }
        if (orderDetailList.size() > 0) {
            OrderBuyer buyer = orderBuyerService.selectOneByWhr("orderid=" + orderid);
            MatchOrgan organ = matchOrganService.get(buyer.getOrganid());            
            multiplePayInputParameter.setSuborders(orderDetailList);
            multiplePayInputParameter.setTsflag(Integer.parseInt(VestUtils.getEntryMode()));
            multiplePayInputParameter.setRedirectUrl(multiplePayInfo.getRedirectUrl());
            multiplePayInputParameter.setPaystoreid(organ.getMcid());
            multiplePayInputParameter.setClientIp(getClientIp());
            LOGGER_ORDERPAYBIZIMPL.debug("吾享支付接口调用，封装数据：{}", multiplePayInputParameter.toString());
            result = orderPayOnlineBiz.mergePayOnline(multiplePayInputParameter);
            if (result.getReturnCode() != 1) {
                throw new PayFailException(result.getErrorText());
            } else {
                if (result.getData() != null) {
                    Map<String, Object> map  = ((Map<String, Object>) result.getData());
                    map.put("orderid", orderid);
                }
            }            
        }
        return result;
    }

    /**
     * 获取客户端ip地址
     * @return 客户端ip地址
     */
    private String getClientIp() {
        return "114.114.114.114";
    }
    
    /**
     * 根据商城的支付类型转换成吾享支付接口的支付类型
     * @param paymentMode 商城支付类型 0:线下 1:吾享(商龙云钱包) 2:微信 3:支付宝 4:预付货款
     * @return 吾享接口支付方式（5：闪惠 6：微信 7：百度钱包 8：支付宝 20：商龙云钱包）
     */
    private Integer getWuxiangPaytypeid(Integer paymentMode) {
        Integer paytypeid = 0;
        if (paymentMode == ConstantBean.EnumPaymentMode.WuXiang.getCode()) {
            paytypeid = ConstantBean.EnumWuxiangPaytypeid.WuXiang.getCode();
        } else if (paymentMode == ConstantBean.EnumPaymentMode.WeChat.getCode()) {
            paytypeid = ConstantBean.EnumWuxiangPaytypeid.WeChat.getCode();
        } else if (paymentMode == ConstantBean.EnumPaymentMode.Alipay.getCode()) {
            paytypeid = ConstantBean.EnumWuxiangPaytypeid.Alipay.getCode();
        }
        return paytypeid;
    }

    /**
     * 根据吾享接口支付类型来转换成商城支付类型
     * @param paytypeid 吾享接口支付类型 （5：闪惠 6：微信 7：百度钱包 8：支付宝 20：商龙云钱包）
     * @return 商城支付类型 0:线下 1:吾享(商龙云钱包) 2:微信 3:支付宝 4:预付货款
     */
    private Integer getPaymentMode(Integer paytypeid) {
        if (paytypeid == ConstantBean.EnumWuxiangPaytypeid.WuXiang.getCode()) {
            return ConstantBean.EnumPaymentMode.WuXiang.getCode();
        } else if (paytypeid == ConstantBean.EnumWuxiangPaytypeid.WeChat.getCode()) {
            return ConstantBean.EnumPaymentMode.WeChat.getCode();
        } else if (paytypeid == ConstantBean.EnumWuxiangPaytypeid.Alipay.getCode()) {
            return ConstantBean.EnumPaymentMode.Alipay.getCode();
        } else {
            throw new PayFailException(messageSourceUtils.getMessage("order.wrong.paymode", new Object[]{paytypeid}));
        }
    }
    
    /**
     * 获取合并支付的各个订单信息封装对象
     * @param orderid 订单id
     * @param money 支付金额
     * @return 订单支付的信息
     */
    public MultiplePayOrder getPayOrder(Long orderid, BigDecimal money) {
        // 拼数据调用支付接口
        Order order = orderService.get(orderid);
        List<OrderItem> oiList = orderItemService.selectByWhr("orderid=" + orderid);
        List<OrderItemProduct> list = orderItemProductService.selectByWhr("orderid=" + orderid);
        OrderSeller os = orderSellerService.selectOneByWhr("orderid=" + orderid);
        if (StringUtils.isEmpty(os.getMcid())) {
            LOGGER_ORDERPAYBIZIMPL.error(">>>>Loss Seller Shop mcid!!!!");
            throw new PayFailException(messageSourceUtils.getMessage("order.wrong.lossmcid", null));
        }
        //主体
        MultiplePayOrder payDataInfo = new MultiplePayOrder();
        payDataInfo.setDismoney(0.0);
        payDataInfo.setMoney(money.doubleValue());
        payDataInfo.setOrderid(order.getOrdernumber());
        payDataInfo.setStoreid(os.getMcid());
        payDataInfo.setTablenum(String.valueOf(os.getOrganid()));
        //明细
        List<MultiplePayOrderItem> payDataItemInfoList = new ArrayList<>();
        for (OrderItemProduct oip : list) {
            MultiplePayOrderItem payDataItemInfo = new MultiplePayOrderItem();
            payDataItemInfo.setItemid(String.valueOf(oip.getProductid()));
            payDataItemInfo.setItemname(oip.getPname());
            payDataItemInfo.setPrice(oip.getPrice().doubleValue());
            for (OrderItem oi : oiList) {
                if (oip.getOrderitemid().equals(oi.getId())) {
                    payDataItemInfo.setItemcount(oi.getItemquantity());
                }
            }
            payDataItemInfoList.add(payDataItemInfo);
        }
        payDataInfo.setItems(payDataItemInfoList);
        return payDataInfo;
    }

    /**
     * 生成单据的支付记录
     * @param orderid 订单id
     * @param amount 支付金额
     * @param paymentmode 商城支付方式（0:线下 1:吾享(商龙云钱包) 2:微信 3:支付宝 4:预付货款 ）
     */
    public void createPayment(Long orderid, BigDecimal amount, Integer paymentmode) {
        Date now = new Date();
        OrderPayment payment = new OrderPayment();
        payment.setOrderid(orderid);
        payment.setCreateDate(now);
        payment.setCancelstatus(false);
        payment.setPaymenttype(1);
        payment.setAmount(amount);
        payment.setArchivestatus(false);
        payment.setModifyDate(now);
        payment.setPaymentnumber("");
        payment.setPaymentdate(now);
        payment.setPaymentmode(paymentmode);
        payment.setTsflag(Integer.parseInt(VestUtils.getEntryMode()));
        payment.setMergeflag(Integer.parseInt(VestUtils.getPayTogether()));
        orderPaymentService.save(payment);
    }
    
    /**
     * 验证订单是否处于可支付状态（如果有一种已支付的线上支付方式那么就不允许支付了）
     * @param multiplePayInfo 合并支付数据封装DTO
     */
    @SuppressWarnings("unchecked")
    private void orderPaymentValidation(MultiplePayInfo multiplePayInfo) {
        boolean payedflag = false;//是否已经支付
        List<MultiplePayOrderInfo> orderList = multiplePayInfo.getOrders();
        for (MultiplePayOrderInfo order : orderList) {
            Order curorder = orderService.get(order.getOrderid());
            OrderStatus orderStatus = orderStatusService.selectOneByWhr("orderid=" + order.getOrderid());
            OrderSeller orderSeller = orderSellerService.selectOneByWhr("orderid=" + order.getOrderid());
            if (orderStatus.getOrderstatus() > OrderStatusEnum.WAIT_PAY.getCode()) {
                payedflag = true;
                break;
            } else {
                List<OrderPayment> paymentList = orderPaymentService.selectByWhr("orderid=" + order.getOrderid());
                for (OrderPayment payment : paymentList) {
                    if (payment.getPaymentmode() == ConstantBean.EnumPaymentMode.WuXiang.getCode() ||
                            payment.getPaymentmode() == ConstantBean.EnumPaymentMode.WeChat.getCode() ||
                            payment.getPaymentmode() == ConstantBean.EnumPaymentMode.Alipay.getCode()) {
                        if (payment.getArchivestatus()) {
                            payedflag = true;
                            break;
                        } else {
                            InterCachePayValues cachedPayValues = null;
                            if (payment.getMergeflag() + payment.getTsflag() == 0) {
                                cachedPayValues = (CachedPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_PAY_VALUES);
                            } else {
                                cachedPayValues = (CachedTsPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_TS_PAY_VALUES);
                            }
                            PayQueryInputParameter payQueryInputParameter = new PayQueryInputParameter();
                            payQueryInputParameter.setOrderid(curorder.getOrdernumber());
                            payQueryInputParameter.setPaytypeid(getWuxiangPaytypeid(payment.getPaymentmode()));
                            payQueryInputParameter.setStoreid(orderSeller.getMcid());
                            String queryUrl = cachedPayValues.getPayWuxiangStateQueryUrl();
                            String publickey = cachedPayValues.getPayWuxiangPublickey64();
                            IResultParameter crp = null;
                            try {
                                @SuppressWarnings("unused")
                                FutureWrapper<IResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> 
                                    {
                                        try {
                                            gt.queryPayState(payQueryInputParameter, queryUrl, publickey);
                                        } catch (Exception e) {
                                            LOGGER_ORDERPAYBIZIMPL.error(e.getMessage());
                                        }
                                    }, 
                                    IResultParameter.class );
//                                crp = iWuXiangPayment.queryPayState(payQueryInputParameter, cachedPayValues.getPayWuxiangStateQueryUrl(), cachedPayValues.getPayWuxiangPublickey64());
                                crp = wrapper.get();
                                if (crp.getReturnCode() == 1) {
                                    //返回值是 0 代表已支付
                                    if ("0".equals(((PayQueryResultParameter)crp).getData().getTrade_state())) {
                                        payedflag = true;
                                        break;
                                    }
                                } else {
                                    //订单不存在返回406
                                    if (!"406".equals(crp.getErrorCode())) {
                                        LOGGER_ORDERPAYBIZIMPL.error("订单支付状态查询报错:{} 错误编:{} 阻碍切换支付方式", crp.getErrorText(), crp.getErrorCode());
                                        payedflag = true;
                                        break;
                                    } else {
                                        LOGGER_ORDERPAYBIZIMPL.error("订单支付状态查询报错:{} 错误编:{} 不阻碍更换支付方式", crp.getErrorText(), crp.getErrorCode());
                                    }
                                }
                            } catch (Exception e) {
                                LOGGER_ORDERPAYBIZIMPL.error("订单支付状态查询报错:{} 阻碍切换支付方式", e.toString());
                                payedflag = true;
                                break;
                            }
                        }
                    } 
                }
            }
            if (payedflag) {
                throw new PayFailException(messageSourceUtils.getMessage("order.pay.fail.orderpayed", new String [] {curorder.getOrdernumber()})) ;
            }
        }
    }
    
    /**
     * 验证卖家店铺是否支持选择的支付方式
     * @param multiplePayInfo 合并支付数据封装DTO
     */
    private void payModelEffectiveValidation(MultiplePayInfo multiplePayInfo) {
        List<MultiplePayOrderInfo> orderList = multiplePayInfo.getOrders();
        for (MultiplePayOrderInfo order : orderList) {
            OrderSeller orderSeller = orderSellerService.selectOneByWhr("orderid=" + order.getOrderid());
            if (orderSeller == null) {
                throw new PayFailException(messageSourceUtils.getMessage("order.wrong.lossseller", null));
            } else {
                Shop shop = shopService.get(orderSeller.getShopid());
                if (shop == null) {
                    throw new PayFailException(messageSourceUtils.getMessage("order.wrong.lossseller", null));
                } else {
                    if (EnumShopPaymode.NONE.getCode() == shop.getPaymode()) {
                        continue;
                    } else {
                        for (PaymentInfo payment : order.getPaymentList()) {
                            if (ConstantBean.PAYMODE_FREE.contains(payment.getPaymentMode())) {
                                continue;
                            } else if (EnumShopPaymode.ONLINE.getCode() == shop.getPaymode()) {
                                if (ConstantBean.PAYMODE_ONLINE.contains(payment.getPaymentMode())) {
                                    continue;
                                } else {
                                    throw new ShopRefusePaymentException(shop.getName(), messageSourceUtils.getMessage("global.paymentmode." + payment.getPaymentMode(), null));
                                }
                            } else if (EnumShopPaymode.OFFLINE.getCode() == shop.getPaymode()){
                                if (ConstantBean.PAYMODE_OFFLINE.contains(payment.getPaymentMode())) {
                                    continue;
                                } else {
                                    throw new ShopRefusePaymentException(shop.getName(), messageSourceUtils.getMessage("global.paymentmode." + payment.getPaymentMode(), null));
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 合并支付处理（单笔的）
     * @param orderDetailInfo 封装的单笔的订单数据
     * @return 结果返回信息
     */
    @Override
    @Transactional
    public IResultParameter orderPay(OrderInfo orderinfo) {
        // TODO Auto-generated method stub
        Order order = orderService.get(Long.parseLong(orderinfo.getOid()));
        if (order != null) {
            List<PaymentInfo> paymentList = new ArrayList<>();
            PaymentInfo payment  = new PaymentInfo();
            payment.setMoney(order.getFinalprice());
            if (orderinfo.getPaytype() == null) {
                payment.setPaymentMode(getPaymentMode(orderinfo.getPaytypeid()));
            } else {
                payment.setPaymentMode(orderinfo.getPaytype());
            }            
            payment.setRedirectUrl(orderinfo.getRedirectUrl());
            paymentList.add(payment);
            
            List<MultiplePayOrderInfo> orderList = new ArrayList<>();            
            MultiplePayOrderInfo orderInfo = new MultiplePayOrderInfo();
            orderInfo.setOrderid(Long.parseLong(orderinfo.getOid()));            
            orderInfo.setPaymentList(paymentList);
            orderList.add(orderInfo);
            
            MultiplePayInfo multiplePayInfo = new MultiplePayInfo();
            multiplePayInfo.setRedirectUrl(orderinfo.getRedirectUrl());
            if (orderinfo.getPaytype() == null) {
                multiplePayInfo.setUnificationPayment(getPaymentMode(orderinfo.getPaytypeid()));
            } else {
                multiplePayInfo.setUnificationPayment(orderinfo.getPaytype());
            }
            multiplePayInfo.setOrders(orderList);
            return orderPay(multiplePayInfo);
        } else {
            throw new PayFailException("缺少必要的订单信息"); 
        }
    }

    @Override
    public IResultParameter orderRefund(OrderInfo orderInfo) throws Exception {
        Order order = orderService.get(Long.parseLong(orderInfo.getOid()));
        if (order != null) {     
            OrderStatus os = orderStatusService.selectOneByWhr("orderid="+order.getId());
            if (os != null && os.getOrderstatus() > 1) {
                throw new Exception("当前订单已处于无法撤销付款的状态");
            }
            OrderBuyer buyer = orderBuyerService.selectOneByWhr("orderid="+order.getId());
            UserInfo info = (UserInfo) SecurityUtils.getSubject().getPrincipal();
            if (info.getSyscodeid().longValue() != order.getSyscodeid().longValue()) {
                LOGGER_ORDERPAYBIZIMPL.error("{}想撤销订单编号为{}的付款，但是此订单不属于该用户", info.getTel(), order.getOrdernumber());
                throw new Exception("当前登录人身份没有权利操作此订单");
            }else {
                if (info.getOrganInfo() != null
                        && info.getOrganInfo().getId().longValue() != buyer.getOrganid().longValue()) {
                    LOGGER_ORDERPAYBIZIMPL.error("{}想撤销订单编号为{}的付款，但是此订单不属于该用户", info.getTel(), order.getOrdernumber());
                    throw new Exception("当前登录人身份没有权利操作此订单");
                }
            }    
            
            OrderSeller orderSeller = orderSellerService.selectOneByWhr("orderid=" + order.getId());
            BaseSimpleInputParameter payCancelInputParameter = new BaseSimpleInputParameter();
            payCancelInputParameter.setOrderid(order.getOrdernumber());
            payCancelInputParameter.setPaytypeid(getWuxiangPaytypeid(orderInfo.getPaytype()));            
            payCancelInputParameter.setStoreid(orderSeller.getMcid());
            
            Map<String,Object> map = new HashMap<>();
            map.put("orderid", Long.parseLong(orderInfo.getOid()));
            map.put("paymentmode", orderInfo.getPaytype());
            OrderPayment payment = orderPaymentService.selectOneByWhr0("orderid=#{orderid} and paymentmode=#{paymentmode}", map);
            if (payment != null) {
                InterCachePayValues cachedPayValues = null;
                if (payment.getMergeflag() + payment.getTsflag() == 0) {
                    cachedPayValues = (CachedPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_PAY_VALUES);
                } else {
                    cachedPayValues = (CachedTsPayValues) memProvider.get(ConstantBean.WUXIANG_CACHED_TS_PAY_VALUES);
                }
                String payCancelUrl = cachedPayValues.getPayWuxiangCommPayCancelUrl();
                String publicckey64 = cachedPayValues.getPayWuxiangPublickey64();
                try {
                    @SuppressWarnings("unchecked")
                    FutureWrapper<IResultParameter> wrapper = FutureWrapper.wrapper( wuXiangPayment, gt -> {
                        try {
                            gt.commPayCancel(payCancelInputParameter, 
                                    payCancelUrl, 
                                    publicckey64);
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }, IResultParameter.class );
                    return wrapper.get();
                } catch (Exception e) {
                    LOGGER_ORDERPAYBIZIMPL.error(e.getMessage());
                    throw e;
                }
//                return (IResultParameter) wuXiangPayment.commPayCancel(
//                        payCancelInputParameter, 
//                        cachedPayValues.getPayWuxiangCommPayCancelUrl(), 
//                        cachedPayValues.getPayWuxiangPublickey64());
            } else {
                LOGGER_ORDERPAYBIZIMPL.error("订单id【{}】的{}支付记录不存在！！", orderInfo.getOid(), orderInfo.getPaytype());
                throw new Exception("该订单的支付记录已不存在！！"); 
            }
        } else {
            LOGGER_ORDERPAYBIZIMPL.error("订单id【{}】的订单不存在！！", orderInfo.getOid());
            throw new Exception("该订单已不存在");
        }
    }
}
